﻿using System;
using Xpedite.WebAbstraction;

/* Copyright (c) 2010 CBaxter
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), 
 * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 
 * IN THE SOFTWARE. 
 */

namespace Xpedite.Resources
{
  internal interface IResourceUrl
  {
    Boolean IsLocal { get; }
    String VirtualPath { get; }
    String PhysicalPath { get; }

    Uri ToUri();
  }

  internal class ResourceUrl : IResourceUrl
  {
    private readonly Uri _virtualUrl;
    private readonly String _virtualPath;
    private readonly String _physicalPath;
    private readonly Boolean _isLocalResource;
    
    public Boolean IsLocal { get { return _isLocalResource; } }
    public String VirtualPath { get { return _virtualPath; } } 
    public String PhysicalPath { get { return _physicalPath; } }

    public ResourceUrl(IWebRequest request)
      : this(request, request.Url)
    { }

    public ResourceUrl(IWebRequest request, String resourceUrl)
      : this(request, new Uri(resourceUrl, UriKind.RelativeOrAbsolute))
    { }

    public ResourceUrl(IWebRequest request, Uri resourceUrl)
    {
      Verify.NotNull(request, "request");
      Verify.NotNull(request, "resourceUrl");

      _virtualUrl = new Uri(request.Url, resourceUrl);
      _virtualPath = GetVirtualPath(request.Url, resourceUrl, _virtualUrl);
      _isLocalResource = _virtualPath.StartsWith(request.ApplicationPath);
      _physicalPath = _isLocalResource ? request.MapPath(_virtualUrl.AbsolutePath) : null; //NOTE: MapPath call is expensive; consider Lazy invoke in property?
    }

    private String GetVirtualPath(Uri baseUrl, Uri resourceUrl, Uri virtualUrl)
    {
      return !resourceUrl.IsAbsoluteUri || String.Compare(baseUrl.GetLeftPart(UriPartial.Authority), resourceUrl.GetLeftPart(UriPartial.Authority), StringComparison.OrdinalIgnoreCase) == 0
             ? virtualUrl.PathAndQuery
             : virtualUrl.AbsoluteUri;
    }

    public Uri ToUri()
    {
      return _virtualUrl;
    }

    public override String ToString()
    {
      return VirtualPath;
    }
  }
}
